package com.icehand.axon.controller;

import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.agent.model.Member;
import com.ecwid.consul.v1.agent.model.Service;
import com.ecwid.consul.v1.health.model.Check;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author icehand
 */
@RestController
@RequestMapping("/consul")
public class ConsulController {
    private final ConsulClient consulClient;

    @Autowired
    public ConsulController(ConsulClient consulClient) {
        this.consulClient = consulClient;
    }

    @GetMapping("/cleanServices")
    public Object cleanServices() {
        List<Service> clearedServices = new ArrayList<>();
        getNodes().forEach(m -> {
            ConsulClient cc = new ConsulClient(m.getAddress());
            getNodeServices(cc).forEach((k, v) -> {
                if (removeService(cc, v)) {
                    clearedServices.add(v);
                }
            });
        });
        return clearedServices;
    }

    @DeleteMapping("/node")
    public Object cleanNodes(String nodeName) {
        return consulClient.agentForceLeave(nodeName);
    }

    @GetMapping("/nodes")
    public List<Member> getNodes() {
        return consulClient.getAgentMembers().getValue();
    }

    @GetMapping("/services")
    public Map<String, Service> getServices(String nodeIp) {
        ConsulClient cc = new ConsulClient(nodeIp);
        return getNodeServices(cc);
    }

    private Boolean removeService(ConsulClient client, Service service) {
        Response<List<Check>> checkList = consulClient.getHealthChecksForService(service.getService(), null);
        List<Check> checks = checkList.getValue();
        //获取健康状态值  PASSING：正常  WARNING  CRITICAL  UNKNOWN：不正常
        Check.CheckStatus checkStatus = checks.get(0).getStatus();
        if (checkStatus != Check.CheckStatus.PASSING) {
            client.agentServiceDeregister(service.getId());
            return true;
        }
        return false;
    }

    private Map<String, Service> getNodeServices(ConsulClient cc) {
        try {
            return cc.getAgentServices().getValue();
        } catch (Exception e) {
            return Collections.EMPTY_MAP;
        }

    }
}
